//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014-2015, Egret Technology Inc.
//  All rights reserved.
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Egret nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
//  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
//  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////

class Main extends eui.UILayer {
    public static instance: Main;
    
    /**
     * 加载进度界面
     * loading process interface
     */
    private loadingView: LoadingUI;
    protected createChildren(): void {
        super.createChildren();
        //inject the custom material parser
        //注入自定义的素材解析器
        var assetAdapter = new AssetAdapter();
        this.stage.registerImplementation("eui.IAssetAdapter",assetAdapter);
        this.stage.registerImplementation("eui.IThemeAdapter",new ThemeAdapter());
        //Config loading process interface
        //设置加载进度界面
        this.loadingView = new LoadingUI();
        this.stage.addChild(this.loadingView);
        // initialize the Resource loading library
        //初始化Resource资源加载库
        RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);
        RES.loadConfig("resource/default.res.json", "resource/");
    }
    /**
     * 配置文件加载完成,开始预加载皮肤主题资源和preload资源组。
     * Loading of configuration file is complete, start to pre-load the theme configuration file and the preload resource group
     */
    private onConfigComplete(event:RES.ResourceEvent):void {
        RES.removeEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);
        // load skin theme configuration file, you can manually modify the file. And replace the default skin.
        //加载皮肤主题配置文件,可以手动修改这个文件。替换默认皮肤。
        var theme = new eui.Theme("resource/default.thm.json", this.stage);
        theme.addEventListener(eui.UIEvent.COMPLETE, this.onThemeLoadComplete, this);

        RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);
        RES.addEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, this.onItemLoadError, this);
        RES.loadGroup("preload");
    }
    private isThemeLoadEnd: boolean = false;
    /**
     * 主题文件加载完成,开始预加载
     * Loading of theme configuration file is complete, start to pre-load the 
     */
    private onThemeLoadComplete(): void {
        this.isThemeLoadEnd = true;
        this.createScene();
    }
    private isResourceLoadEnd: boolean = false;
    /**
     * preload资源组加载完成
     * preload resource group is loaded
     */
    private onResourceLoadComplete(event:RES.ResourceEvent):void {
        if (event.groupName == "preload") {
            this.stage.removeChild(this.loadingView);
            RES.removeEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);
            RES.removeEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, this.onItemLoadError, this);
            this.isResourceLoadEnd = true;
            this.createScene();
        }
    }
    private createScene(){
        if(this.isThemeLoadEnd && this.isResourceLoadEnd){
            this.startCreateScene();
        }
    }
    
    /**
     * 资源组加载出错
     *  The resource group loading failed
     */
    private onItemLoadError(event:RES.ResourceEvent):void {
        console.warn("Url:" + event.resItem.url + " has failed to load");
    }
    /**
     * 资源组加载出错
     * Resource group loading failed
     */
    private onResourceLoadError(event:RES.ResourceEvent):void {
        //TODO
        console.warn("Group:" + event.groupName + " has failed to load");
        //忽略加载失败的项目
        //ignore loading failed projects
        this.onResourceLoadComplete(event);
    }
    /**
     * preload资源组加载进度
     * loading process of preload resource
     */
    private onResourceProgress(event:RES.ResourceEvent):void {
        if (event.groupName == "preload") {
            this.loadingView.setProgress(event.itemsLoaded, event.itemsTotal);
        }
    }
    /**
     * 创建场景界面
     * Create scene interface
     */
    protected startCreateScene(): void {
        Main.instance = this;
        this.socket = new egret.WebSocket();
        this.socket.type = egret.WebSocket.TYPE_BINARY;
        this.socket.connectByUrl("ws://192.168.31.188:8080/api");
        this.socket.addEventListener(egret.ProgressEvent.SOCKET_DATA,this.handleSocketEvent,this);
        this.socket.addEventListener(egret.Event.CONNECT,this.handleSocketEvent,this);
        this.socket.addEventListener(egret.Event.CLOSE,this.handleSocketEvent,this);
    }

    private handleSocketEvent(evt: egret.Event): void {
        switch(evt.type) {
            case egret.ProgressEvent.SOCKET_DATA:
                var bytes: egret.ByteArray = new egret.ByteArray();
                this.socket.readBytes(bytes);
                bytes.position = 0;
                this.register.decodeStream(bytes);
                break;
            case egret.Event.CONNECT:
                console.log("连接成功.");
                this.register = new neo.tetris.rpc.message.MessageHandlerRegister();
                this.register.userMessage = new neo.tetris.rpc.messageImpl.UserMessageImpl();
                this.register.battleMessage = new neo.tetris.rpc.messageImpl.BattleMessageImpl();
                this.register.systemMessage = new neo.tetris.rpc.messageImpl.SystemMessageImpl();
                this.userService = new neo.tetris.rpc.service.UserService();
                this.userService.socket = this.socket;
                this.battleService = new neo.tetris.rpc.service.BattleService();
                this.battleService.socket = this.socket;
                this.battleService = new neo.tetris.rpc.service.BattleService();
                this.battleService.socket = this.socket;
                neo.tetris.model.appInstance.addEventListener(neo.typescript.model.Bean.PROPERTY_CHANGE,this.handleAppChanged,this);
                this.handleAppChanged();
                break;
            case egret.Event.CLOSE:
                console.log("连接关闭");
                break;
        }
    }

    private socket: egret.WebSocket;
    
    private register: neo.tetris.rpc.message.MessageHandlerRegister;
    
    public userService: neo.tetris.rpc.service.UserService;
    
    public battleService: neo.tetris.rpc.service.BattleService;
    
    public loginView: neo.tetris.view.LoginView;

    public matchView: neo.tetris.view.MatchView;

    public battleView: neo.tetris.view.BattleView;

    private handleAppChanged(evt: egret.Event = null): void {
        if(!evt || evt.data == neo.tetris.model.App.LOGINED) {
            if(neo.tetris.model.appInstance.logined) {
                if (this.loginView) {
                    this.loginView.parent.removeChild(this.loginView);
                    this.loginView = null;
                }
                this.battleView = new neo.tetris.view.BattleView()
                this.addChild(this.battleView);
                this.matchView = new neo.tetris.view.MatchView();
                neo.tetris.model.appInstance.logined.addEventListener(neo.typescript.model.Bean.PROPERTY_CHANGE,this.handleAppUserChanged,this);
                this.handleAppUserChanged();
            } else {
                this.addChild(this.loginView = new neo.tetris.view.LoginView());
            }
        }
        if (!evt || evt.data == neo.tetris.model.App.BATTLE) {
            if (neo.tetris.model.appInstance.battle) {
                neo.tetris.model.appInstance.battle.addEventListener(neo.typescript.model.Bean.PROPERTY_CHANGE,this.handleBattleChanged,this);
                this.handleBattleChanged();
            }
        }
    }

    private handleAppUserChanged(evt: egret.Event = null): void {
        
    }
    
    private handleBattleChanged(evt:egret.Event = null):void {
        if (!evt || evt.data == neo.tetris.model.BattleModel.START_TIME) {
            if(isNaN(neo.tetris.model.appInstance.battle.startTime)
                || neo.tetris.model.appInstance.battle.startTime < neo.tetris.model.appInstance.serverTime) {
                this.addChild(this.matchView);
            } else {
                this.matchView.fadeOut(700);
                /*
                if(neo.tetris.model.appInstance.battle.startTime > neo.tetris.model.appInstance.serverTime) {
                    egret.setTimeout(
                        function() { this.removeChild(this.matchView); },this,neo.tetris.model.appInstance.battle.startTime - neo.tetris.model.appInstance.serverTime
                    )    
                } else {
                    this.removeChild(this.matchView);
                }
                */
            }
        } else if (!evt || evt.data == neo.tetris.model.BattleModel.WINNER) {
            if(neo.tetris.model.appInstance.battle.winner) {
                if(neo.tetris.model.appInstance.battle.winner.userUUid == neo.tetris.model.appInstance.logined.uuid)
                    this.addChild(new neo.tetris.view.BattleResultWinnerView("resource/custom_skins/BattleResultWinnerSkin.exml"));
                else
                    this.addChild(new neo.tetris.view.BattleResultWinnerView("resource/custom_skins/BattleResultloserSkin.exml"));
            }
        }
    }
}
